package studyguide.ch15;

import java.io.IOException;

import javax.microedition.io.Connector;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.TextMessage;

public class SMSMidlet extends MIDlet {

	private static final int SMS_PORT = 1234;
	
	private final Command sendCommand;
	private final Command exitCommand;
	private final Display display;
	
	private final Form mainForm;
	
	private final TextField address;
	private final TextField message;
	
	private final TextField receivedMessages;
	
	private class SampleCommandListener implements CommandListener {
		public void commandAction(Command command, Displayable displayable) {
			if (command == exitCommand) {
				destroyApp(true);
				notifyDestroyed();
			} else if (command == sendCommand) {
				Thread thread = new Thread(new NetworkSender());
				thread.start();
			} else {
				throw new RuntimeException("UNKNOWN COMMAND" + command);
			}
		}
	}
	
	private class NetworkSender implements Runnable {
		public void run() {
			MessageConnection conn = null;
			try {
				conn = (MessageConnection) 
					Connector.open("sms://" + address.getString() + ":" + SMS_PORT);
				TextMessage smsMessage = (TextMessage) conn.newMessage(MessageConnection.TEXT_MESSAGE);
				smsMessage.setPayloadText(message.getString());
				conn.send(smsMessage);
			} catch (IOException e) {
				receivedMessages.setString("Error:" + e.getMessage());
			} finally {
				if (conn != null) {
					try {
						conn.close();
					} catch (IOException e) {
						receivedMessages.setString("Error:" + e.getMessage());
					}
				}
			}
		}
	}
	
	private class NetworkReceiver implements Runnable {
		public void run() {
			MessageConnection conn = null;
			try {
				conn = (MessageConnection) Connector.open("sms://:" + SMS_PORT);
				
				while (true) {
					TextMessage message = (TextMessage) conn.receive();
					receivedMessages
						.insert("From " + message.getAddress() + "[" 
								+ message.getPayloadText() + "]\n", 
								receivedMessages.size());
				}
			} catch (IOException e) {
				receivedMessages.setString("Error:" + e.getMessage());
			} finally {
				if (conn != null) {
					try {
						conn.close();
					} catch (IOException e) {
						receivedMessages.setString("Error:" + e.getMessage());
					}
				}
			}
		}
	}
	
	public SMSMidlet() throws IOException {
		mainForm = new Form("SMS Sample");
		exitCommand = new Command("Exit", Command.EXIT, 1);
		sendCommand = new Command("Send", Command.SCREEN, 1);
		
		address = new TextField("Phone number:", "", 15, TextField.ANY);
		message = new TextField("Message:", "", 50, TextField.ANY);
		receivedMessages = new TextField("Received messages:", "", 500, TextField.ANY);
		
		mainForm.addCommand(sendCommand);
		mainForm.addCommand(exitCommand);
		
		SampleCommandListener listener = new SampleCommandListener();
		mainForm.setCommandListener(listener);
		
		mainForm.append(address);
		mainForm.append(message);
		mainForm.append(receivedMessages);

		display = Display.getDisplay(this);
		
		// Start a thread to listen to messages:
		Thread thread = new Thread(new NetworkReceiver());
		thread.start();
	}
	
	protected void destroyApp(boolean unconditional) {
	}

	protected void pauseApp() {
	}

	protected void startApp() throws MIDletStateChangeException {
		display.setCurrent(mainForm);
	}
	
}
